<template>
  <view class="preview">
    <!-- <u-navbar back-text="返回" title="剑未配妥，出门已是江湖"></u-navbar> -->
    <swiper
      class="swiper"
      :autoplay="false"
      :indicator-dots="false"
      :current="currentIndex"
      @change="debouncedHandleChange"
      :duration="300"
    >
      <swiper-item
        v-for="(item, index) in classStore.categoryDetailList"
        :key="item._id"
      >
        <!-- 解释：v-if="index===currentIndex"
          这样可以实现swiper-item的预加载，提高用户体验 有能节省用户流量
        -->
        <u-image
          v-if="readImgs.includes(index)"
          width="100%"
          height="100%"
          class="preview-image"
          :src="getLargeImageUrl(item.smallPicurl)"
          mode="aspectFill"
          @error="handleImageLoadError(index)"
          :lazy-load="true"
          :fade-show="true"
        />
      </swiper-item>
    </swiper>

    <view class="absolute-mask">
      <view class="goBack-btn" @click="goBack">
        <u-icon name="arrow-left" color="#fff" size="60"></u-icon>
      </view>
      <view class="count">
        <text class="count-current">{{ currentIndex + 1 }}</text>
        <text class="count-separator">/</text>
        <text class="count-total">{{ classStore.total }}</text>
      </view>
      <view class="time">
        {{ $u.timeFormat(timestamp, 'hh:MM') }}
      </view>
      <view class="date">
        {{ $u.timeFormat(timestamp, 'mm月dd日') }}
      </view>
      <view class="footer">
        <view class="footer-item info" @click="getWallpaperInfo">
          <u-icon name="info-circle" color="#3fcec6" size="50"></u-icon>
          <text class="footer-text">信息</text>
        </view>

        <view class="footer-item star" @click="syncGetUserScore">
          <u-icon name="star" color="#3fcec6" size="50"></u-icon>
          <text class="footer-text">评分</text>
        </view>

        <view class="footer-item download" @click="downloadWallpaper">
          <u-icon name="download" color="#3fcec6" size="50"></u-icon>
          <text class="footer-text">下载</text>
        </view>
      </view>
    </view>
    <!-- 顶部的信息 popup弹出框 -->
    <view class="popup">
      <u-popup
        v-model="isPopupShow"
        mode="bottom"
        height="40%"
        :safe-area-inset-bottom="true"
        :closeable="true"
      >
        <view class="popup-content">
          <!-- 顶部的标题 -->
          <view class="popup-content-title">
            <u-text
              text="壁纸信息"
              size="28"
              type="info"
              :block="true"
              align="center"
              margin="20rpx 0"
            ></u-text>
          </view>
          <!-- info组合 -->
          <view class="wrapper-info">
            <view class="wrapper-ID">
              <u-text text="壁纸ID:" type="info"></u-text>
              <u-text :text="wallpaperInfo.ID" lines="1"></u-text>
            </view>
            <view class="wrapper-publisher">
              <u-text text="发布者:" type="info"></u-text>
              <u-text :text="wallpaperInfo.publisher" lines="1"></u-text>
            </view>
            <view class="wrapper-rating">
              <u-text text="评分:" type="info" lines="1"></u-text>
              <u-rate
                :count="5"
                :current="wallpaperInfo.rating"
                :disabled="true"
              ></u-rate>
            </view>
            <view class="wrapper-summary">
              <u-text text="摘要:" type="info"></u-text>
              <u-text :text="wallpaperInfo.summary" lines="1"></u-text>
            </view>
            <view class="wrapper-tags">
              <u-text text="标签:" type="info"></u-text>
              <u-tag
                v-for="tag in wallpaperInfo.tags"
                :key="tag"
                :text="tag"
                shape="circle"
                bg-color="#fff"
                border-color="#3fcec6"
                color="#3fcec6"
              ></u-tag>
            </view>
            <Declaration></Declaration>
          </view>
        </view>
      </u-popup>
    </view>

    <!-- 中部的评分 -->
    <view>
      <u-popup
        v-model="isShowRatePopup"
        mode="center"
        :closeable="true"
        border-radius="14"
        width="500rpx"
        height="260rpx"
      >
        <view class="popup-rating">
          <!-- 顶部的标题 -->
          <view class="popup-rating-title">
            <u-text
              text="壁纸评分"
              size="28"
              type="info"
              :block="true"
              align="center"
            ></u-text>
          </view>
          <view class="rating-content">
            <view class="rate">
              <u-rate v-model="rating" gutter="20" size="60"></u-rate>
            </view>
            <u-button
              type="success"
              shape="circle"
              size="medium"
              class="rating-btn"
              :disabled="rating === 0"
              @click="submitRating"
              >确认</u-button
            >
          </view>
        </view>
      </u-popup>
    </view>
  </view>
</template>

<script setup>
  import { useClassStore } from '../../stores/class';
  import Declaration from '@/pages/preview/components/Declaration.vue';
  import { ref, onMounted, onUnmounted, computed } from 'vue';
  import { $u } from 'uview-pro';
  import { onLoad } from '@dcloudio/uni-app';
  import { getCategoryDetailAPI } from '@/api/class';
  import { getWallpaperInfoAPI, submitRatingAPI } from '@/api/category';
  import { useDownloadStore } from '@/stores/download';
import { useRatingStore } from '@/stores/rating';
  const downloadStore = useDownloadStore();
  const ratingStore = useRatingStore();
  // 常量定义
  const PRELOAD_COUNT = 1; // 预加载前后图片数量
  const DEBOUNCE_DELAY = 100; // 防抖延迟时间
  const UPDATE_INTERVAL = 1000; // 时间更新间隔
  const mode = ref(null);
  const currentIndex = ref(0);
  const classStore = useClassStore();
  // 已经看过的图
  const readImgs = ref([]);
  // 此图是否已经评分过了 (这里要注意userScore为undefined时也需要判断 如果上TS就会报错)
  const isRated = computed(() => {
    let currentItem = classStore.categoryDetailList[currentIndex.value];
    return (
      currentItem &&
      currentItem.userScore !== undefined &&
      currentItem.userScore !== 0
    );
  });
  // 将缩略图地址转换为大图地址
  const getLargeImageUrl = smallPicurl => {
    if (!smallPicurl) return '';
    return smallPicurl.replace(/_small\.webp$/, '.jpg');
  };

  // 图片加载错误处理
  const handleImageLoadError = index => {
    console.error(`图片加载失败: ${index}`);
    // 可以在这里添加加载失败后的处理逻辑
    // 比如显示占位图或者重试机制
    $u.toast('图片加载失败，请稍后重试');
  };
  // 壁纸信息
  const wallpaperInfo = ref({
    ID: '',
    classid: '',
    publisher: '',
    rating: 0,
    summary: '',
    tags: [],
    picurl: '',
  });

  // 当前壁纸的选中评分
  const rating = ref(0);
  // 时间戳
  const timestamp = ref(Date.now());
  const isPopupShow = ref(false);
  const isShowRatePopup = ref(false);
  // 更新时间函数
  const updateTime = () => {
    timestamp.value = Date.now();
  };
  // 下载
  const downloadWallpaper = () => {
    if (!wallpaperInfo.value.picurl) {
      $u.toast('图片地址不存在');
      return;
    }

    // 显示加载中
    uni.showLoading({
      title: '正在保存...',
      mask: true,
    });

    // 先检查权限状态
    uni.getSetting({
      success: res => {
        if (res.authSetting['scope.writePhotosAlbum']) {
          // 已有权限，直接下载
          startDownload();
        } else if (res.authSetting['scope.writePhotosAlbum'] === false) {
          // 隐藏加载中
          uni.hideLoading();
          // 用户之前拒绝过，需要手动引导到设置页面
          uni.showModal({
            title: '需要授权',
            content: '保存图片需要访问相册权限，请在设置中开启',
            confirmText: '去设置',
            success: modalRes => {
              if (modalRes.confirm) {
                uni.openSetting({
                  success: settingRes => {
                    if (settingRes.authSetting['scope.writePhotosAlbum']) {
                      // 重新显示加载中并开始下载
                      uni.showLoading({
                        title: '正在保存...',
                        mask: true,
                      });
                      startDownload();
                    } else {
                      $u.toast('权限未开启，无法保存图片');
                    }
                  },
                });
              }
            },
          });
        } else {
          // 从未申请过权限，可以正常申请
          uni.authorize({
            scope: 'scope.writePhotosAlbum',
            success: () => {
              startDownload();
            },
            fail: () => {
              uni.hideLoading();
              $u.toast('需要相册权限才能保存图片');
            },
          });
        }
      },
      fail: () => {
        uni.hideLoading();
        $u.toast('权限检查失败');
      },
    });
  };

  // 开始下载
  const startDownload = () => {
    uni.getImageInfo({
      src: wallpaperInfo.value.picurl,
      success: res => {
        uni.saveImageToPhotosAlbum({
          filePath: res.path,
          success: () => {
            uni.hideLoading();
            $u.toast('保存成功', 'success');
            
            // 下载成功将当前壁纸添加到下载列表
            // 要根据id来找 将classStore.categoryDetailList的数据复制一份到downloadStore.downloadList
            let _id = wallpaperInfo.value.ID;
            let item = classStore.categoryDetailList.find(
              item => item._id === _id
            );
            if (item) {
              downloadStore.addDownloadList(item);
            }
          },
          fail: () => {
            uni.hideLoading();
            $u.toast('保存失败');
          },
        });
      },
      fail: () => {
        uni.hideLoading();
        $u.toast('下载域名失效,请反馈');
      },
    });
  };
  const getWallpaperInfo = async () => {
    try {
      const res = await getWallpaperInfoAPI(wallpaperInfo.value.ID);
      // 处理接口返回的数据结构
      if (res.data && res.data.length > 0) {
        const data = res.data[0];
        wallpaperInfo.value = {
          ID: data._id,
          classid: data.classid,
          publisher: data.nickname,
          rating: parseFloat(data.score) || 0,
          summary: data.description,
          tags: data.tabs || [],
          // picurl: getLargeImageUrl(data.smallPicurl),
        };
      }
      isPopupShow.value = true;
    } catch {
      $u.toast('好像出了点问题，刷新试试');
    }
  };
  onLoad(options => {
    // 拿取模式 (如果是category进来的就要禁止滑到最后一张进行加载 最多就9张)
    mode.value = options.mode || null;
    if (mode.value === 'category') {
      currentIndex.value = 0;
    }

    // 拿取ID
    wallpaperInfo.value.ID = options.id;

    // 找到当前观看的索引
    currentIndex.value = classStore.categoryDetailList.findIndex(
      item => item._id === wallpaperInfo.value.ID
    );

    // 安全检查：确保currentIndex有效
    if (
      currentIndex.value >= 0 &&
      currentIndex.value < classStore.categoryDetailList.length
    ) {
      // 拿取classid
      wallpaperInfo.value.classid =
        classStore.categoryDetailList[currentIndex.value].classid;
      // 拿取图片的大图地址
      let currentItem = classStore.categoryDetailList[currentIndex.value];
      if (currentItem && currentItem.smallPicurl) {
        wallpaperInfo.value.picurl = getLargeImageUrl(currentItem.smallPicurl);
      }
    } else {
      $u.toast('未找到对应的图片数据，ID:', options.id);
    }

    // 刚进入的时候拿第一次看的那张图片 以及提前加载前后两个图片 准备做缓存
    readImgs.value.push(
      currentIndex.value - PRELOAD_COUNT,
      currentIndex.value,
      currentIndex.value + PRELOAD_COUNT
    );
    // 去重和去除-1
    readImgs.value = [...new Set(readImgs.value)].filter(
      item => item !== -1 && item < classStore.categoryDetailList.length
    );
  });
  // 返回功能
  const goBack = () => {
    uni.navigateBack();
  };
  const syncGetUserScore = () => {
    rating.value =
      classStore.categoryDetailList[currentIndex.value].userScore || 0;
    isShowRatePopup.value = true;
  };
  const submitRating = async () => {
    if (rating.value === 0) {
      $u.toast('请选择评分');
      return;
    } else if (isRated.value) {
      $u.toast('已评分过！', 'error');
      return;
    } else {
      // 发送请求  （在方法的参数中携带id）
      try {
        let res = await submitRatingAPI({
          classid: wallpaperInfo.value.classid,
          wallId: wallpaperInfo.value.ID,
          userScore: rating.value,
        });
        if (res.errCode === 0) {
          // 评分成功后 添加壁纸到评分的pinia
          let _id = wallpaperInfo.value.ID;
          let item = classStore.categoryDetailList.find(
            item => item._id === _id
          );
          if (item) {
            // 添加评分时间和评分分数
            const ratedItem = {
              ...item,
              userScore: rating.value,
              ratingTime: Date.now()
            };
            ratingStore.addRatingList(ratedItem);
          }
          
          // 评分结束后存储好当前壁纸
          $u.toast('感谢您的评分', 'success');
          // 在这里追加一个评分的回显
          classStore.categoryDetailList[currentIndex.value].userScore =
            rating.value;
        }
      } catch (error) {
        console.error('评分提交失败:', error);
        $u.toast('评分提交失败，请稍后重试', 'error');
      } finally {
        // 重置评分
        rating.value = 0;
        // 关闭弹窗
        isShowRatePopup.value = false;
      }
    }
  };
  const getCategoryDetail = async () => {
    try {
      const res = await getCategoryDetailAPI({
        classid: classStore.classid,
        pageNum: classStore.pageNum,
        pageSize: classStore.pageSize,
      });
      classStore.addCategoryDetailList(res.data);
    } catch {
      $u.toast('好像出了点问题，刷新试试');
    }
  };

  // 处理swiper变化
  const handleChange = async e => {
    // 先将classid赋值
    classStore.classid =
      classStore.categoryDetailList[e.detail.current].classid;
    // 在列表中找出_id给ID
    wallpaperInfo.value.ID =
      classStore.categoryDetailList[e.detail.current]._id;
    currentIndex.value = e.detail.current;
    // 找到picurl
    let currentItem = classStore.categoryDetailList[e.detail.current];
    if (currentItem && currentItem.smallPicurl) {
      wallpaperInfo.value.picurl = getLargeImageUrl(currentItem.smallPicurl);
    }
    // 如果在预览滑到了已加载的最后一页 就再发请求拿数据(提前两张再发请求)
    if (
      currentIndex.value === classStore.categoryDetailList.length - 2 &&
      !mode.value
    ) {
      // 再发请求
      if (!mode.value) {
        classStore.pageNum++;
        await getCategoryDetail();
      }
    }
    // 每次切换swiper-item 都将当前swiper-item的索引 以及前后两个索引 加入缓存数组中
    readImgs.value.push(
      currentIndex.value - PRELOAD_COUNT,
      currentIndex.value,
      currentIndex.value + PRELOAD_COUNT
    );
    // 去重和去除-1
    readImgs.value = [...new Set(readImgs.value)].filter(item => item >= 0);
  };

  // 添加防抖的滑动处理
  let slideTimer = null;
  const debouncedHandleChange = e => {
    if (slideTimer) clearTimeout(slideTimer);
    slideTimer = setTimeout(() => {
      handleChange(e);
    }, DEBOUNCE_DELAY);
  };
  // 定时器变量
  let timer = null;
  onMounted(() => {
    updateTime();
    // 每秒更新一次时间
    timer = setInterval(updateTime, UPDATE_INTERVAL);
  });

  onUnmounted(() => {
    // 清理所有定时器
    if (timer) {
      clearInterval(timer);
      timer = null;
    }
    if (slideTimer) {
      clearTimeout(slideTimer);
      slideTimer = null;
    }
    // 清空数组引用，帮助垃圾回收
    readImgs.value = [];
  });
</script>

<style scoped lang="scss">
  // 全屏的图片 全部使用继承即可
  .preview {
    position: relative;
    width: 100%;
    height: 100vh;

    swiper {
      width: 100%;
      height: 100%;

      swiper-item {
        width: 100%;
        height: 100%;
      }
    }

    .absolute-mask {
      .goBack-btn {
        border: 1rpx solid #fff;
        position: absolute;
        top: 8vh;
        left: 6vw;
        background-color: rgba(0, 0, 0, 0.5);
        border-radius: 50%;
        padding: 10rpx;
        transform: scale(1);
        transition: transform 0.15s ease;
        &:active {
          transform: scale(0.9);
        }
      }
      //  下面统一使用的居中方式都是 left: 50%; transform: translateX(-50%); 快捷方便 原理 左边偏移50% 再按照自己的宽度偏移-50% 就居中了
      .count {
        position: absolute;
        background: rgba(0, 0, 0, 0.4);
        top: 8vh;
        left: 50%;
        transform: translateX(-50%);
        color: #fff;
        border-radius: 40rpx;
        padding: 12rpx 24rpx;
        font-size: 26rpx;
        backdrop-filter: blur(10px);
        border: 1px solid rgba(255, 255, 255, 0.15);
        font-weight: 500;
        letter-spacing: 1rpx;
        display: flex;
        align-items: center;
        gap: 8rpx;
        transition: all 0.3s ease;

        // 悬停效果
        &:hover {
          background: rgba(0, 0, 0, 0.6);
          border-color: rgba(255, 255, 255, 0.25);
          transform: translateX(-50%) scale(1.05);
        }

        // 当前页数样式
        .count-current {
          color: #3fcec6;
          font-weight: 600;
          font-size: 28rpx;
        }

        // 分隔符样式
        .count-separator {
          color: rgba(255, 255, 255, 0.6);
          margin: 0 4rpx;
        }

        // 总页数样式
        .count-total {
          color: rgba(255, 255, 255, 0.8);
          font-size: 24rpx;
        }
      }
      .time {
        position: absolute;
        top: 12vh;
        left: 50%;
        transform: translateX(-50%);
        color: #fff;
        padding: 10rpx 20rpx;
        font-size: 160rpx;
        font-weight: 200;
        letter-spacing: -2rpx;
        transition: all 0.3s ease;

        // 秒级跳动动画
        animation: timePulse 1s ease-in-out infinite;

        @keyframes timePulse {
          0%,
          100% {
            opacity: 1;
            transform: translateX(-50%) scale(1);
          }
          50% {
            opacity: 0.8;
            transform: translateX(-50%) scale(0.98);
          }
        }
      }
      .date {
        position: absolute;
        top: 24vh;
        left: 50%;
        transform: translateX(-50%);
        color: #fff;
        padding: 10rpx 20rpx;
        font-size: 40rpx;
      }
      .footer {
        backdrop-filter: blur(10rpx);
        position: absolute;
        bottom: 10vh;
        left: 50%;
        transform: translateX(-50%);
        color: #fff;
        padding: 20rpx 40rpx;
        display: flex;
        align-items: center;
        gap: 60rpx;
        background: rgba(0, 0, 0, 0.7);
        border-radius: 50rpx;
        border: 1px solid rgba(255, 255, 255, 0.2);
        box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.3);
        transition: all 0.3s ease;

        &:hover {
          background: rgba(0, 0, 0, 0.8);
          box-shadow: 0 6rpx 30rpx rgba(0, 0, 0, 0.4);
        }

        .footer-item {
          display: flex;
          flex-direction: column;
          align-items: center;
          gap: 12rpx;
          cursor: pointer;
          transition: transform 0.2s ease;

          &:hover {
            transform: scale(1.05);
          }

          &:active {
            transform: scale(0.95);
          }

          .footer-text {
            font-size: 24rpx;
            color: #fff;
            font-weight: 600;
            letter-spacing: 1rpx;
            text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.8);
            transition: all 0.2s ease;
          }
        }
      }
    }
  }
  .wrapper-info {
    padding: 26rpx;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    gap: 20rpx;
  }
  .rating-content {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 20rpx;
  }
</style>
